package edu.hawaii.duedates.lenders.libraries;

import java.util.ArrayList;
import java.util.Calendar;
import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.HttpUnitOptions;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;

import edu.hawaii.duedates.BorrowedItem;
import edu.hawaii.duedates.LenderQuery;

public class UhManoaLibraryQuery extends LenderQuery {
  private final String logonFormName;
  private final String field1Name;
  private final String loginFailedText;
  private final String field2Name;
  private boolean success = false;
  private WebConversation conversation;
  
  private final String id;
  private final String lastName;
  
  public UhManoaLibraryQuery(String id, String lastName) {
    // constants
    this.lenderName = "University of Hawaii at Manoa";
    this.lenderUrl = "http://uhmanoa.lib.hawaii.edu/cgi-bin/Pwebrecon.cgi?DB=local&PAGE=pbLogon";
    this.logonFormName = "logonpage";
    this.field1Name = "BC";
    this.field2Name = "LN";
    this.loginFailedText = "Sorry, Login unsuccessful.";
    this.conversation = new WebConversation();

    // credentials
    this.id = id;
    this.lastName = lastName;

    logIn();
    if (success) {
      processBorrowedItemsPage();
    }
  }
  
  public boolean isValid() {
    return success;
  }

  @Override
  protected void logIn() {
    try {
      // Website has bogus JavaScript code.
      HttpUnitOptions.setExceptionsThrownOnScriptError(false);
      
      WebRequest request = new GetMethodWebRequest(this.lenderUrl);
      WebResponse response = this.conversation.getResponse(request);
      
      WebForm form = response.getFormWithName(this.logonFormName);
      form.setParameter(this.field1Name, this.id);
      form.setParameter(this.field2Name, this.lastName);
      form.submit();
      
      response = this.conversation.getCurrentPage();
      
      if (response.getText().contains(loginFailedText)) {
        System.out.println("Wrong user name or password.");
        this.success = false;
      }
      else {
        this.success = true;
      }
    }
    catch (Exception e) {
      System.out.println("Unable to log in.");
      this.success = false;
    }
  }

  @Override
  protected void processBorrowedItemsPage() {
    this.borrowedItems = new ArrayList<BorrowedItem>();
    try {
      WebResponse response = this.conversation.getCurrentPage();
      WebTable table;
      
      if (!response.getText().contains("You have no items checked out.")) {
        if (response.getText().contains("Renew?")) {
          table = response.getTableStartingWith("Renew?");
        }
        else {
          // required for the test accounts that don't have a Renew column
          table = response.getTableStartingWith("Item");
        }
        
        Calendar newDate;
        String newTitle;
        for (int i = 1; i < table.getRowCount(); i++) {
          if (response.getText().contains("Renew?")) {
            newTitle = parseTitle(table.getCellAsText(i, 1));
            newDate = parseDate(table.getCellAsText(i, 3));
          }
          else {
            newTitle = parseTitle(table.getCellAsText(i, 0));
            newDate = parseDate(table.getCellAsText(i, 2));
          }
          BorrowedItem newBorrowedItem = new BorrowedItem(newDate, newTitle); 
          this.borrowedItems.add(newBorrowedItem);
        }
      }
    }
    catch (Exception e) {
      System.out.println("Failed to parse UH table");
    }
  }
  
  /**
   * Separates the title of the library book from it's author and returns the resulting string.
   * When querying the UH Manoa Library system, it displays the author followed by two spaces and
   * then the title of the library material. 
   * 
   * @param bookInfo The information string associated with a checked out.
   * @return The title of the checked out item.
   */
  private String parseTitle(String bookInfo) {
    return bookInfo.replaceAll("(.*)  (.*)  (.*)", "$2");
  }
  
  private Calendar parseDate(String date) {
    // needs improvement
    String[] dateParts = date.split("-");
    dateParts[0] = dateParts[0].split(" ")[3];
    Calendar newDate = Calendar.getInstance();
    newDate.set(Calendar.MONTH, Integer.valueOf((dateParts[0])) - 1);
    newDate.set(Calendar.DAY_OF_MONTH, Integer.valueOf(dateParts[1]));
    newDate.set(Calendar.YEAR, Integer.valueOf(dateParts[2]) + 2000);
    return newDate; 
  }
}
